package fixmodel.test;

import fixmodel.adapter.GooseAdapter;
import fixmodel.base.Quack;
import fixmodel.combination.Flock;
import fixmodel.decor.QuackCounter;
import fixmodel.entity.Goose;
import fixmodel.factory.AbstractDuckFactory;
import fixmodel.factory.CountingDuckFactory;
import fixmodel.observable.QuackLogiest;


/**模拟器 会产生一些鸭子对象 并且能确认鸭子会呱呱叫
 * @author yaojianfeng
 */
public class DuckSimulator {
    public static void main(String[] args) {
        DuckSimulator duckSimulator = new DuckSimulator();
        //创建工厂 实例化不同的工厂 就可以创建不同类的鸭子
        AbstractDuckFactory duckFactory = new CountingDuckFactory();
        duckSimulator.simulate(duckFactory);

    }

    private void simulate(AbstractDuckFactory duckFactory){
        Quack mallardDuck  = duckFactory.creatMallardDuck();
        Quack redHeadDuck  = duckFactory.creatRedHead();
        Quack rubberDuck  = duckFactory.creatRubberDuck();
        Quack duckCall  = duckFactory.creatDuckCall();
        Quack duckGoose  = duckFactory.creatGoose();

        //鹅 被适配为鸭子
        Quack gooseDuck  = new GooseAdapter(new Goose());
        GooseAdapter adapter = (GooseAdapter) gooseDuck;
        adapter.getGoose().honk();
        //被适配过的鹅 又被装饰了一次
        Quack gooseDuckDecor  = new QuackCounter(gooseDuck);

        System.out.println("鸭子模拟器:使用了鹅适配器将鹅适配为鸭子");
        //先创建一个Flock 然后把许多Quack塞给它,这个是主群
        Flock flockDucks = new Flock();
        flockDucks.add(mallardDuck);
        flockDucks.add(redHeadDuck);
        flockDucks.add(rubberDuck);
        flockDucks.add(duckCall);
        flockDucks.add(duckGoose);


        //创建绿头鸭小家族
        Flock mallardFlock = new Flock();
        Quack mallardDuck1 = duckFactory.creatMallardDuck();
        Quack mallardDuck2 = duckFactory.creatMallardDuck();
        Quack mallardDuck3 = duckFactory.creatMallardDuck();
        Quack mallardDuck4 = duckFactory.creatMallardDuck();
        Quack mallardDuck5 = duckFactory.creatMallardDuck();


        //将绿头鸭加入鸭子群
        mallardFlock.add(mallardDuck1);
        mallardFlock.add(mallardDuck2);
        mallardFlock.add(mallardDuck3);
        mallardFlock.add(mallardDuck4);
        mallardFlock.add(mallardDuck5);

        //将绿头鸭群加入主群
        flockDucks.add(mallardFlock);

        //模拟各种鸭子叫
        simulate(mallardDuck);
        simulate(redHeadDuck);
        simulate(rubberDuck);
        simulate(duckCall);
        //使用了适配器 所以鹅也可以把它当做鸭子的Quack对象 如果不包装该适配对象 则不会被计数
        simulate(gooseDuck);
        // 被适配器适配成鸭子的鹅 也会被计数
        simulate(gooseDuckDecor);
        simulate(duckGoose);
        System.out.println("============测试一群鸭子叫===================");
        simulate(flockDucks);
        System.out.println("=============只测试绿头鸭子叫======================");
        simulate(mallardFlock);


        System.out.println("使用观察者模式");
        QuackLogiest quackLogiest = new QuackLogiest();
        //模拟观察绿头鸭
        mallardDuck.registerObserver(quackLogiest);

        //flockDucks.registerObserver(quackLogiest);

        simulate(mallardDuck);
        System.out.println("====================");
        simulate(flockDucks);

        mallardFlock.registerObserver(quackLogiest);
        simulate(mallardFlock);


        System.out.println("鸭子叫的次数:"+QuackCounter.getNumberOfQuacks()+"次");
    }

    /**
     * 重载方法 模拟一只鸭子
     * @param duck
     */
    private void simulate(Quack duck){
        duck.quack();
    }













}
